home *** CD-ROM | disk | FTP | other *** search
/ Resource Library: Multimedia / Resource Library: Multimedia.iso / sgml / msdos / sgml07 / modsgml1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-20  |  14.0 KB  |  459 lines

  1. #include "sgmlincl.h"         /* #INCLUDE statements for SGML parser. */
  2.  
  3. #define ETDCON (tags[ts].tetd->etdmod->ttype)     /* ETD content flags. */
  4.  
  5. /* SGML: Main SGML driver routine.
  6. */
  7. enum sgmlevent sgmlnext(rcbdafp, rcbtagp)
  8. struct rcbdata *rcbdafp;
  9. struct rcbtag *rcbtagp;
  10. {
  11.      while (prologsw && !conactsw) {
  12.           conact = parsepro();
  13.           conactsw = 0;       /* Assume sgmlact() will not be skipped. */
  14.           switch(conact) {
  15.  
  16.           case PIS_:
  17.           case EOD_:
  18.                conactsw = 1;   /* We can skip sgmlact() in opening state. */
  19.                break;
  20.  
  21.           case DAF_:
  22.                newetd = stagreal = ETDCDATA;
  23.                conact = stag(datarc = DAF_);
  24.                conactsw = 1;   /* We can skip sgmlact() in opening state. */
  25.                prologsw = 0;   /* End the prolog. */
  26.                break;
  27.  
  28.       case MSS_:
  29.            conactsw = 1;
  30.            /* fall through */
  31.           default:             /* DCE_ PEP_: not defined in SGMLACT.H. */
  32.                if (msplevel==0) conpcb = getpcb((int)ETDCON);
  33.                prologsw = 0;   /* End the prolog. */
  34.                break;
  35.           }
  36.      }
  37.      for (;;) {
  38.       unsigned swact;  /* Switch action: saved conact, new, or sgmlact.*/
  39.  
  40.           if (conactsw) {
  41.            conactsw = 0;
  42.            swact = conact;
  43.            contersw = contersv;
  44.       }
  45.           else {
  46.            conact = parsecon(tbuf, conpcb);
  47.            swact = sgmlact((UNCH)(conact != EOD_ ? conact : LOP_));
  48.       }
  49.  
  50.           switch (swact) {
  51.  
  52.           case MD_:           /* Process markup declaration. */
  53.                parsenm(tbuf, NAMECASE); /* Get declaration name. */
  54.                if (!ustrcmp(tbuf+1, key[KUSEMAP])) mdsrmuse(tbuf);
  55.                else sgmlerr(E_MDNAME, conpcb, tbuf+1, (UNCH *)0);
  56.                continue;
  57.           case MDC_:           /* Process markup declaration comment. */
  58.                if (*FPOS!=lex.d.mdc)
  59.                     parsemd(tbuf, NAMECASE, (struct parse *)0, NAMELEN);
  60.                continue;
  61.  
  62.           case MSS_:           /* Process marked section start. */
  63.                conpcb = mdms(tbuf, conpcb);
  64.                continue;
  65.           case MSE_:           /* Process marked section end (drop to LOP_). */
  66.                if (mdmse()) conpcb = getpcb((int)ETDCON);
  67.                continue;
  68.  
  69.           case PIS_:           /* Return processing instruction (string). */
  70.                if (entpisw) rcbdafp->data = data;
  71.                else {
  72.                     parselit(tbuf, &pcblitc, PILEN, lex.d.pic);
  73.                     rcbdafp->data = tbuf;
  74.                }
  75.                rcbdafp->datalen = datalen;
  76.                rcbdafp->contersw = entpisw;
  77.            entpisw = 0;             /* Reset for next time.*/
  78.                scbset();                /* Update location in current scb. */
  79.                return SGMLPIS;
  80.  
  81.           case ETG_:               /* Return end-tag. */
  82.                charmode = 0;       /* Not in char mode unless CDATA or RCDATA.*/
  83.                if (msplevel==0) conpcb = getpcb((int)ETDCON);
  84.                rcbtagp->contersw = tags[ts+1].tflags;
  85.                rcbtagp->tagmin = etagimsw ? MINETAG : etagmin;
  86.                rcbtagp->curgi = tags[ts+1].tetd->etdgi;
  87.                rcbtagp->ru.oldgi = tags[ts].tetd->etdgi;
  88.                if (etagmin==MINSTAG) rcbtagp->tagreal =
  89.                      BADPTR(stagreal) ? stagreal : (PETD)stagreal->etdgi;
  90.                else rcbtagp->tagreal =
  91.                      BADPTR(etagreal) ? etagreal : (PETD)etagreal->etdgi;
  92.                rcbtagp->etictr = etictr;
  93.                rcbtagp->srmnm = tags[ts].tsrm!=SRMNULL ? tags[ts].tsrm[0]->ename
  94.                                                       : 0;
  95.                scbset();                /* Update location in current scb. */
  96.                return SGMLETG;
  97.  
  98.           case STG_:               /* Return start-tag. */
  99.                charmode = 0;       /* Not in char mode unless CDATA or RCDATA.*/
  100.                if (!conrefsw && msplevel==0) conpcb = getpcb((int)ETDCON);
  101.                rcbtagp->contersw = tags[ts].tflags;
  102.                rcbtagp->tagmin = dostag ? MINSTAG : stagmin;
  103.                rcbtagp->curgi = tags[ts].tetd->etdgi;
  104.                /* Get attribute list if one was defined for this element. */
  105.                rcbtagp->ru.al = !tags[ts].tetd->adl ? 0 :
  106.                     rcbtagp->tagmin==MINNONE  ? al : tags[ts].tetd->adl;
  107.                rcbtagp->tagreal = BADPTR(stagreal)?stagreal:(PETD)stagreal->etdgi;
  108.                rcbtagp->etictr = etictr;
  109.                rcbtagp->srmnm = tags[ts].tsrm!=SRMNULL ? tags[ts].tsrm[0]->ename
  110.                                                       : 0;
  111.                scbset();                /* Update location in current scb. */
  112.                return SGMLSTG;
  113.  
  114.           case DAF_:               /* Return data in source entity buffer. */
  115.                charmode = 1;
  116.                rcbdafp->datalen = datalen;
  117.                rcbdafp->data = data;
  118.                rcbdafp->contersw = contersw | entdatsw;
  119.                                contersw = entdatsw = 0;/* Reset for next time.*/
  120.                scbset();                /* Update location in current scb. */
  121.                return SGMLDAF;
  122.  
  123.           case CON_:               /* Process conact after returning REF_. */
  124.                conactsw = 1;
  125.                contersv = contersw;
  126.           case REF_:               /* Return RE found. */
  127.                if (badresw) {
  128.                     badresw = 0;
  129.                     sgmlerr(E_CHARS, &pcbconm, tags[ts].tetd->etdgi+1, (UNCH *)0);
  130.                     continue;
  131.                }
  132.                charmode = 1;
  133.                rcbdafp->contersw = contersw;
  134.                contersw = 0;        /* Reset for next time.*/
  135.                scbset();                /* Update location in current scb. */
  136.                return SGMLREF;
  137.  
  138.           case EOD_:               /* End of source document entity. */
  139.                if (mslevel != 0) sgmlerr(139, conpcb, (UNCH *)0, (UNCH *)0);
  140.            idrck();                /* Check idrefs. */
  141.                scbset();                /* Update location in current scb. */
  142.                return SGMLEOD;
  143.  
  144.           default:             /* LOP_: Loop again with no action. */
  145.                continue;
  146.           }
  147.      }
  148. }
  149. /* PCBSGML: State and action table for action codes returned to text processor
  150.             by SGML.C.  It causes a REF_ to be handled as follows:
  151.             ST1: Ignore first REF_ of content if no DAF, ETG, or RS intervenes.
  152.             NR1: Process REF_ if it is a REF-only record (null record).
  153.             DA1: Save REF_ if record contains data.
  154.             NR2: (REF_ pending) Process REF_ if it is a null record.
  155.             ST2: (REF_ pending) Ignore REF_ if no MD_, PIS_, or DAF_ intervenes.
  156.             Columns are based on SGMLACT.H values minus DAF_, except that end
  157.             of document has input code LOP_, regardless of its action code.
  158. */
  159. /* Symbols for state names (end with a number). */
  160. #define ST1     0   /* Trailing STG_ or markup record: ignore REF_. */
  161. #define NR1     2   /* New record: return immediate REF_. */
  162. #define DA1     4   /* Data or element found: save REF_. */
  163. #define NR2     6   /* New record with REF_ pending: return immediate REF_. */
  164. #define ST2     8   /* REF_ pending; return it and conact except ETG EOD. */
  165.  
  166. static UNCH sgmltab[10][12] = {
  167. /*daf_ etg_ md_  mdc_ mss_ mse_ pis_ ref_ stg_ etgp_rsr_ eod  */
  168.   DA1 ,DA1 ,ST1 ,ST1 ,ST1 ,ST1 ,ST1 ,NR1 ,ST1 ,ST1 ,NR1 ,ST1 ,/*st1*/
  169.   DAF_,ETG_,MD_ ,MDC_,MSS_,MSE_,PIS_,LOP_,STG_,ETG_,LOP_,EOD_,
  170.  
  171.   DA1 ,DA1 ,ST1 ,ST1 ,ST1 ,ST1 ,ST1 ,NR1 ,ST1 ,DA1 ,NR1 ,ST1 ,/*nr1*/
  172.   DAF_,ETG_,MD_ ,MDC_,MSS_,MSE_,PIS_,REF_,STG_,ETG_,LOP_,EOD_,
  173.  
  174.   DA1 ,DA1 ,DA1 ,DA1 ,DA1 ,DA1 ,DA1 ,NR2 ,ST1 ,DA1 ,NR1 ,ST1 ,/*da1*/
  175.   DAF_,ETG_,MD_ ,MDC_,MSS_,MSE_,PIS_,LOP_,STG_,ETG_,LOP_,EOD_,
  176.  
  177.   DA1 ,DA1 ,ST2 ,ST2 ,ST2 ,ST2 ,ST2 ,NR2 ,ST1 ,ST2 ,NR2 ,ST1 ,/*nr2*/
  178.   CON_,ETG_,MD_ ,MDC_,MSS_,MSE_,PIS_,REF_,CON_,ETG_,LOP_,EOD_,
  179.  
  180.   DA1 ,DA1 ,ST2 ,ST2 ,ST2 ,ST2 ,ST2 ,NR2 ,ST1 ,ST2 ,NR2 ,ST1 ,/*st2*/
  181.   CON_,ETG_,MD_ ,MDC_,MSS_,MSE_,PIS_,LOP_,CON_,ETG_,LOP_,EOD_
  182. };
  183. int scbsgmst = ST1;           /* SCBSGML: trailing stag or markup; ignore RE. */
  184. int scbsgmnr = NR1;           /* SCBSGML: new record; do not ignore RE. */
  185. /* SGMLACT: Determine action to be taken by SGML.C based on current state and
  186.             specified input.
  187.             For start or end of a plus exception element, push or pop the
  188.             pcbsgml stack.
  189.             Return to caller with action code.
  190. */
  191. #ifdef USE_PROTOTYPES
  192. int sgmlact(UNCH conret)
  193. #else
  194. int sgmlact(conret)
  195. UNCH conret;                  /* Action returned to SGML.C by content parse. */
  196. #endif
  197. {
  198.  
  199.      if (conret==STG_ && GET(tags[ts].tflags, TAGPEX))
  200.           {++pss; scbsgml[pss].snext = ST1;}
  201.      scbsgml[pss].sstate = scbsgml[pss].snext;
  202.      scbsgml[pss].snext = sgmltab[scbsgml[pss].sstate]
  203.                                     [scbsgml[pss].sinput = conret-DAF_];
  204.      scbsgml[pss].saction = sgmltab[scbsgml[pss].sstate+1][scbsgml[pss].sinput];
  205.      TRACEGML(scbsgml, pss, conactsw, conact);
  206.      return (int)scbsgml[(conret==ETG_ && GET(tags[ts+1].tflags, TAGPEX)) ?
  207.                          pss-- : pss].saction;
  208. }
  209. #undef ST1
  210. #undef NR1
  211. #undef DA1
  212. #undef NR2
  213. #undef ST2
  214. /* GETPCB: Choose pcb for new or resumed element.
  215. */
  216. struct parse *getpcb(etdcon)
  217. int etdcon;                   /* Content type of new or resumed element. */
  218. {
  219.      if (BITON(etdcon, MGI)) {
  220.           return(BITON(etdcon, MCHARS) ? &pcbconm : &pcbcone);
  221.      }
  222.      if (BITON(etdcon, MCDATA) || BITON(etdcon, MRCDATA)) {
  223.          charmode = 1;
  224.          return(BITON(etdcon, MCDATA) ? &pcbconc : (rcessv = es, &pcbconr));
  225.      }
  226.      return(&pcbconm);
  227. }
  228.  
  229. struct markup *sgmlset(swp)
  230. struct switches *swp;
  231. {
  232.      /* Initialize variables based on switches structure members. */
  233.      sw = *swp;
  234.      nonchbuf[0] = sw.delnonch;    /* Prefix delimiter for non-SGML char.*/
  235.      rbufs = (UNCH *)rmalloc((UNS)3+sw.swbufsz) + 3; /* DOS file read area. */
  236.      /* Initialize lexical tables for non-SGML char prefix delimiter. */
  237.      lexcnm[sw.delnonch] = lexcon[sw.delnonch] = lexlms[sw.delnonch] = lex.l.lmnsc;
  238.      TRACEPRO();         /* Set trace switches for prolog. */
  239.      msginit(swp);
  240.      ioinit(swp);
  241.      sdinit();
  242.      return &lex.m;
  243. }
  244.  
  245. /* Points for each capacity, indexed by enum capacity.  We'll replace
  246. 2 with the real NAMELEN at run time. */
  247.  
  248. static UNCH cappoints[] = {
  249.      1,
  250.      2,
  251.      1,
  252.      2,
  253.      2,
  254.      2,
  255.      2,
  256.      2,
  257.      1,
  258.      2,
  259.      2,
  260.      1,
  261.      2,
  262.      2,
  263.      2,
  264.      2,
  265.      2
  266. };
  267.  
  268. static long capnumber[NCAPACITY];
  269. static long maxsubcap[NCAPACITY];
  270.  
  271. VOID sgmlend(p)
  272. struct sgmlcap *p;
  273. {
  274.      int i;
  275.      for (; es >= 0; --es)
  276.       if (FILESW)
  277.            fileclos();
  278.  
  279.      capnumber[NOTCAP] = ds.dcncnt;
  280.      capnumber[EXGRPCAP] = ds.pmexgcnt;
  281.      capnumber[ELEMCAP] = ds.etdcnt+ds.etdercnt;
  282.      capnumber[EXNMCAP] = ds.pmexcnt;
  283.      capnumber[GRPCAP] = ds.modcnt;
  284.      capnumber[ATTCAP] = ds.attcnt;
  285.      capnumber[ATTCHCAP] = ds.attdef;
  286.      capnumber[AVGRPCAP] = ds.attgcnt;
  287.      capnumber[IDCAP] = ds.idcnt;
  288.      capnumber[IDREFCAP] = ds.idrcnt;
  289.      capnumber[ENTCAP] = ds.ecbcnt;
  290.      capnumber[ENTCHCAP] = ds.ecbtext;
  291.      capnumber[MAPCAP] = ds.srcnt + ds.srcnt*lex.s.dtb[0].mapdata;
  292.      capnumber[NOTCHCAP] = ds.dcntext;
  293.  
  294.      capnumber[TOTALCAP] = 0;
  295.  
  296.      for (i = 1; i < NCAPACITY; i++)
  297.       capnumber[i] += maxsubcap[i];
  298.      for (i = 1; i < NCAPACITY; i++) {
  299.       if (cappoints[i] > 1)
  300.            cappoints[i] = NAMELEN;
  301.       capnumber[TOTALCAP] += (long)capnumber[i] * cappoints[i];
  302.      }
  303.      p->number = capnumber;
  304.      p->points = cappoints;
  305.      p->limit = sd.capacity;
  306.      p->name = captab;
  307.  
  308.      for (i = 0; i < NCAPACITY; i++) {
  309.       long excess = capnumber[i]*cappoints[i] - sd.capacity[i];
  310.       if (excess > 0) {
  311.            char buf[sizeof(long)*3 + 1];
  312.            sprintf(buf, "%ld", excess);
  313.            sgmlerr(162, (struct parse *)0,
  314.                (UNCH *)captab[i], (UNCH *)buf);
  315.       }
  316.      }
  317. }
  318.  
  319. VOID sgmlsubcap(v)
  320. long *v;
  321. {
  322.      int i;
  323.      for (i = 0; i < NCAPACITY; i++)
  324.       if (v[i] > maxsubcap[i])
  325.            maxsubcap[i] = v[i];
  326. }
  327.  
  328. int sgmlsdoc(ptr)
  329. UNIV ptr;
  330. {
  331.      struct entity *e;
  332.      union etext etx;
  333.      etx.x = ptr;
  334.  
  335.      e = entdef(indocent, ESF, &etx);
  336.      if (!e)
  337.       return -1;
  338.      return entopen(e);
  339. }
  340.  
  341. /* SGMLGENT:  Get a data entity.
  342.               Returns:
  343.           -1 if the entity does not exist
  344.           -2 if it is not a data entity
  345.           1 if it is an external entity
  346.           2 if it is an internal cdata entity
  347.           3 if it is an internal sdata entity
  348. */
  349. int sgmlgent(iname, np, tp)
  350. UNCH *iname;
  351. PNE *np;
  352. UNCH **tp;
  353. {
  354.      PECB ep;                 /* Pointer to an entity control block. */
  355.      
  356.      ep = entfind(iname);
  357.      if (!ep)
  358.       return -1;
  359.      switch (ep->estore) {
  360.      case ESN:
  361.       if (np)
  362.            *np = ep->etx.n;
  363.       return 1;
  364.      case ESC:
  365.       if (tp)
  366.            *tp = ep->etx.c;
  367.       return 2;
  368.      case ESX:
  369.       if (tp)
  370.            *tp = ep->etx.c;
  371.       return 3;
  372.      }
  373.      return -2;
  374. }
  375.  
  376. /* Mark an entity. */
  377.  
  378. int sgmlment(iname)
  379. UNCH *iname;
  380. {
  381.      PECB ep;
  382.      int rc;
  383.  
  384.      ep = entfind(iname);
  385.      if (!ep)
  386.       return -1;
  387.      rc = ep->mark;
  388.      ep->mark = 1;
  389.      return rc;
  390. }
  391.  
  392. int sgmlgcnterr()
  393. {
  394.      return msgcnterr();
  395. }
  396.  
  397. /* This is for error handling functions that want to print a gi backtrace. */
  398.  
  399. UNCH *getgi(i)
  400. int i;
  401. {
  402.      return i >= 0 && i <= ts ? tags[i].tetd->etdgi + 1 : NULL;
  403. }
  404.  
  405. /* Returns the value of prologsw for the use by error handling functions. */
  406.  
  407. int inprolog()
  408. {
  409.      return prologsw;
  410. }
  411.  
  412. /* Used by the error handling functions to access scbs. */
  413.  
  414. int getlocation(level, locp)
  415. int level;
  416. struct location *locp;
  417. {
  418.      if (level < 0 || level > es)
  419.       return 0;
  420.      if (locp) {
  421.       int es = level;
  422.       /* source macros access a variable called `es' */
  423.  
  424.       locp->filesw = FILESW;
  425.       locp->rcnt = RCNT;
  426.       locp->ccnt = CCNT;
  427.       locp->ename = ENTITY + 1;
  428.       locp->fcb = SCBFCB;
  429.       locp->curchar = CC;
  430.      }
  431.      return 1;
  432. }
  433.  
  434. int sgmlloc(linenop, filenamep)
  435. unsigned long *linenop;
  436. char **filenamep;
  437. {
  438.      int level = es;
  439.      int es;
  440.  
  441.      for (es = level; es >= 0 && !FILESW; es--)
  442.       ;
  443.      if (es < 0)
  444.       return 0;
  445.      *linenop = RCNT;
  446.      *filenamep = ioflid(SCBFCB);
  447.      return 1;
  448. }
  449.  
  450. /*
  451. Local Variables:
  452. c-indent-level: 5
  453. c-continued-statement-offset: 5
  454. c-brace-offset: -5
  455. c-argdecl-indent: 0
  456. c-label-offset: -5
  457. End:
  458. */
  459.